https://mp.weixin.qq.com/s/4V3Hl6P_Y4HIohKBz6GACg
setState 本身代码的执行肯定是同步的，这里的异步是指是多个 state 会合成到一起进行批量更新。
同步还是异步取决于它被调用的环境。

如果 setState 在 React 能够控制的范围被调用，它就是异步的。
比如合成事件处理函数，生命周期函数， 此时会进行批量更新，也就是将状态合并后再进行 DOM 更新。

如果 setState 在原生 JavaScript 控制的范围被调用，它就是同步的。
比如原生事件处理函数，定时器回调函数，Ajax 回调函数中，此时 setState 被调用后会立即更新 DOM 。

setState 的“异步”并不是说内部由异步代码实现，其实本身执行的过程和代码都是同步的，
只是合成事件和钩子函数的调用顺序在更新之前，导致在合成事件和钩子函数中没法立马拿到更新后的值，
形成了所谓的“异步”，当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。

setState 的批量更新优化也是建立在“异步”（合成事件、钩子函数）之上的，
在原生事件和setTimeout 中不会批量更新，在“异步”中如果对同一个值进行多次setState，
setState的批量更新策略会对其进行覆盖，取最后一次的执行，如果是同时setState多个不同的值，在更新时会对其进行合并批量更新。

React18以后，使用了createRoot api后，所有setState都是异步批量执行的


